package cn.tedu.charging.order.service.impl;

import cn.tedu.charging.common.utils.JsonUtils;
import cn.tedu.charging.order.common.ChargingConstants;
import cn.tedu.charging.order.common.GunStatusCode;
import cn.tedu.charging.common.JsonResult;
import cn.tedu.charging.common.pojo.param.GunStatusUpdateParam;
import cn.tedu.charging.common.pojo.vo.StationInfoVO;
import cn.tedu.charging.common.pojo.vo.UserInfoVO;
import cn.tedu.charging.order.common.MqttConstants;
import cn.tedu.charging.order.feign.DeviceClient;
import cn.tedu.charging.order.feign.UserClient;
import cn.tedu.charging.order.mqtt.MqttProducer;
import cn.tedu.charging.order.pojo.dto.ChargingDto;
import cn.tedu.charging.order.pojo.po.OrderMQPO;
import cn.tedu.charging.order.quartz.DeviceCheckJob;
import cn.tedu.charging.order.rabbit.RabbitMQProducer;
import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.tedu.charging.order.pojo.param.OrderAddParam;
import cn.tedu.charging.order.service.OrderService;

/**
 * @Author: Miyako
 * @Date: 2024-10-12-15:58
 * @Description:
 */
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    UserClient userClient;
    @Autowired
    DeviceClient deviceClient;

    @Autowired
    MqttProducer mqttProducer;

    @Autowired
    private RabbitMQProducer rabbitMQProducer;



    /**
     * 创建订单
     * 1. 生成订单号
     * 2. 获取场站的信息和设备信息(服务之间的调用-feign  订单服务调用设备服务)
     * 3. 获取用户信息(车辆信息) (服务之间的调用-feign 订单服务调用用户服务)
     * 4. 修改充电枪的状态 为 使用中 (服务之间的调用-feign 订单服务调用设备服务)
     * 5. 给设备发送开始充电指令 (物联网 订单服务调用充电桩设备)
     * @param orderAddParam
     * @return orderNo（String）
     */
    @Override
    public String oderCreate(OrderAddParam orderAddParam) {
        String orderNo = getOrderNo();

         StationInfoVO stationInfoVO = getStationInfoByGunId(orderAddParam.getGunId());

        UserInfoVO userInfoVO = getUserInfoByUserId(orderAddParam.getUserId());

        Boolean success = updateGunStatusBusy(orderAddParam.getGunId());
        //给设备发送开始充电指令
        startCharging(orderAddParam.getGunId(), orderNo, orderAddParam.getPileId());
        log.debug("创建自检任务中--- 订单号{}，枪id{}",orderNo,orderAddParam.getGunId());
        try {
            //激活自检任务
            DeviceCheckJob deviceCheckJob = new DeviceCheckJob(orderNo,orderAddParam.getGunId());
        } catch (SchedulerException e) {
            log.debug("创建自检任务失败");
        }

        //设备返回消息并存入数据库后,发送信息给mq做延迟处理
        sendOrderMessage(orderNo);

        return orderNo;

    }

    private Boolean updateGunStatusBusy(Integer gunId) {
        GunStatusUpdateParam gunStatusUpdateParam = new GunStatusUpdateParam();
        gunStatusUpdateParam.setGunId(gunId);
        gunStatusUpdateParam.setStatus(GunStatusCode.GUN_STATUS_BUYS.getCode());
        JsonResult<Boolean> result = deviceClient.updateGunStatus(gunStatusUpdateParam);
            return result.getData();
    }

    private void startCharging(Integer gunId , String orderNo ,Integer pileId) {
        //Topic 枪id
        //Message 充电指令
        String topic = MqttConstants.TOPIC_START_CHARGING_PREFIX+"/"+pileId;

        ChargingDto chargingDto = new ChargingDto();
        chargingDto.setOrderNo(orderNo);
        chargingDto.setGunId(gunId);
        chargingDto.setMsg(ChargingConstants.START_CHARGING);
        chargingDto.setPileId(pileId);
        String msg = JsonUtils.toJson(chargingDto);
        mqttProducer.publish(topic,msg);
        log.debug("订单服务发送开始充电指令到设备:{},消息:{}",topic,chargingDto);
    }

    /**
     * @description:给rabbitmq 传一条消息
     * @author: Miyako
     * @param: []
     * @return: void
     **/
    private void sendOrderMessage(String orderNo){
        OrderMQPO orderMQPO = new OrderMQPO();
        orderMQPO.setOrderNo(orderNo);
        rabbitMQProducer.sendOrder(orderMQPO);
    }

    private UserInfoVO getUserInfoByUserId(Integer userId) {
        JsonResult<UserInfoVO> userInfoVOJsonResult = userClient.userInfo(userId);
        UserInfoVO data = userInfoVOJsonResult.getData();
        return data;

    }

    private StationInfoVO getStationInfoByGunId(Integer gunId) {
        JsonResult<StationInfoVO> stationInfo = deviceClient.getStationInfo(gunId);
        StationInfoVO data = stationInfo.getData();
        return data;
    }




    private String getOrderNo() {
        return "666";
    }
}
